package com.direct.ratelimit;

import java.util.Collection;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.direct.ratelimit.action.Action;
import com.direct.ratelimit.limit.DefaultLimitService;
import com.direct.ratelimit.limit.Limit;
import com.direct.ratelimit.limit.LimitService;
import com.direct.ratelimit.threshold.DefaultThresholdService;
import com.direct.ratelimit.threshold.Threshold;
import com.direct.ratelimit.threshold.ThresholdService;
import com.direct.ratelimit.usage.ResourceUsageDAO;
import com.direct.ratelimit.usage.ResourceUsageService;

public class RateLimiter {

	private static final Logger LOGGER = LoggerFactory.getLogger(RateLimiter.class);
	// void set

	// private LimitService limitService = new DefaultLimitService();

	private ThresholdService thresholdService = new DefaultThresholdService();

	private ResourceUsageService resourceUsageService;

	/**
	 * executes the
	 * 
	 * @return
	 */
	boolean execute(RateLimitRequest rateLimitRequest) {
		// get the time this started
		Date now = new Date();

		// Collection<Limit> limits = limitService.getLimits(rateLimitRequest);
		Collection<Threshold> thresholds = thresholdService.getThresholds(rateLimitRequest);

		// the action to should execute will be the one that
		for (Threshold threshold : thresholds) {
			// threshold.
			long numberOfCalls = resourceUsageService.getResourceUsage(rateLimitRequest, threshold.getLimit().getTimeFrame());
			if (thresholdService.isThresholdExceeded(threshold, numberOfCalls)) {
				LOGGER.debug("threshold: {}, has been exceeded for client: {}", threshold.getLimit().getId(), rateLimitRequest.getClientId());
				Action action = threshold.getAction();
				action.execute();
			}
		}

		return false;
	}

	public void setThresholdService(ThresholdService thresholdService) {
		this.thresholdService = thresholdService;
	}

}
